/**
 * IndexDB 数据库管理器
 * 用于存储桌面应用的所有数据
 */

class IndexedDBManager {
  constructor() {
    this.dbName = 'Win11DesktopDB';
    this.dbVersion = 1;
    this.db = null;
  }

  // 初始化数据库
  async init() {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open(this.dbName, this.dbVersion);

      request.onerror = () => {
        reject(new Error('Failed to open database'));
      };

      request.onsuccess = () => {
        this.db = request.result;
        resolve();
      };

      request.onupgradeneeded = (event) => {
        const db = event.target.result;

        // 用户表
        if (!db.objectStoreNames.contains('users')) {
          const userStore = db.createObjectStore('users', { keyPath: 'uid' });
          userStore.createIndex('username', 'username', { unique: true });
          userStore.createIndex('email', 'email', { unique: true });
        }

        // 文件夹表
        if (!db.objectStoreNames.contains('folders')) {
          const folderStore = db.createObjectStore('folders', { keyPath: 'fid' });
          folderStore.createIndex('parentId', 'parentId');
          folderStore.createIndex('uid', 'uid');
        }

        // 文件表
        if (!db.objectStoreNames.contains('files')) {
          const fileStore = db.createObjectStore('files', { keyPath: 'fid' });
          fileStore.createIndex('folderId', 'folderId');
          fileStore.createIndex('uid', 'uid');
        }

        // 图片表
        if (!db.objectStoreNames.contains('images')) {
          const imageStore = db.createObjectStore('images', { keyPath: 'id' });
          imageStore.createIndex('uid', 'uid');
        }

        // 博客表
        if (!db.objectStoreNames.contains('blogs')) {
          const blogStore = db.createObjectStore('blogs', { keyPath: 'bid' });
          blogStore.createIndex('uid', 'uid');
        }

        // 应用设置表
        if (!db.objectStoreNames.contains('settings')) {
          const settingStore = db.createObjectStore('settings', { keyPath: 'key' });
        }

        // 桌面布局表
        if (!db.objectStoreNames.contains('desktop')) {
          const desktopStore = db.createObjectStore('desktop', { keyPath: 'uid' });
        }
      };
    });
  }

  // 通用数据库操作方法
  async get(storeName, key) {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([storeName], 'readonly');
      const store = transaction.objectStore(storeName);
      const request = store.get(key);

      request.onsuccess = () => resolve(request.result);
      request.onerror = () => reject(request.error);
    });
  }

  async getAll(storeName, indexName = null, indexValue = null) {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([storeName], 'readonly');
      const store = transaction.objectStore(storeName);

      let request;
      if (indexName && indexValue !== undefined) {
        const index = store.index(indexName);
        request = index.getAll(indexValue);
      } else {
        request = store.getAll();
      }

      request.onsuccess = () => resolve(request.result);
      request.onerror = () => reject(request.error);
    });
  }

  async add(storeName, data) {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([storeName], 'readwrite');
      const store = transaction.objectStore(storeName);
      const request = store.add(data);

      request.onsuccess = () => resolve(request.result);
      request.onerror = () => reject(request.error);
    });
  }

  async put(storeName, data) {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([storeName], 'readwrite');
      const store = transaction.objectStore(storeName);
      const request = store.put(data);

      request.onsuccess = () => resolve(request.result);
      request.onerror = () => reject(request.error);
    });
  }

  async delete(storeName, key) {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([storeName], 'readwrite');
      const store = transaction.objectStore(storeName);
      const request = store.delete(key);

      request.onsuccess = () => resolve();
      request.onerror = () => reject(request.error);
    });
  }

  async clear(storeName) {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([storeName], 'readwrite');
      const store = transaction.objectStore(storeName);
      const request = store.clear();

      request.onsuccess = () => resolve();
      request.onerror = () => reject(request.error);
    });
  }

  // 用户相关方法
  async createUser(userData) {
    const defaultUser = {
      uid: this.generateId(),
      username: userData.username,
      email: userData.email,
      password: userData.password,
      avatar: userData.avatar || '',
      background: userData.background || '',
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString()
    };
    await this.add('users', defaultUser);
    return defaultUser;
  }

  async getUserByUsername(username) {
    const users = await this.getAll('users');
    return users.find(user => user.username === username);
  }

  async getUserByEmail(email) {
    const users = await this.getAll('users');
    return users.find(user => user.email === email);
  }

  async updateUser(uid, updateData) {
    const user = await this.get('users', uid);
    if (!user) throw new Error('User not found');

    const updatedUser = {
      ...user,
      ...updateData,
      updatedAt: new Date().toISOString()
    };
    await this.put('users', updatedUser);
    return updatedUser;
  }

  // 文件夹相关方法
  async createFolder(folderData) {
    const defaultFolder = {
      fid: this.generateId(),
      uid: folderData.uid,
      parentId: folderData.parentId || 0,
      name: folderData.name,
      type: 'folder',
      x: folderData.x || 100,
      y: folderData.y || 100,
      width: folderData.width || 100,
      height: folderData.height || 100,
      isStatic: folderData.isStatic || false,
      icon: folderData.icon || '/img/icon/folder.png',
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString()
    };
    await this.add('folders', defaultFolder);
    return defaultFolder;
  }

  async getFoldersByParent(parentId, uid) {
    const allFolders = await this.getAll('folders');
    return allFolders.filter(folder =>
      folder.parentId === parentId && folder.uid === uid
    );
  }

  async updateFolder(fid, updateData) {
    const folder = await this.get('folders', fid);
    if (!folder) throw new Error('Folder not found');

    const updatedFolder = {
      ...folder,
      ...updateData,
      updatedAt: new Date().toISOString()
    };
    await this.put('folders', updatedFolder);
    return updatedFolder;
  }

  async deleteFolder(fid) {
    // 删除文件夹及其所有子项
    const folder = await this.get('folders', fid);
    if (!folder) throw new Error('Folder not found');

    // 删除子文件夹
    const subFolders = await this.getFoldersByParent(fid, folder.uid);
    for (const subFolder of subFolders) {
      await this.deleteFolder(subFolder.fid);
    }

    // 删除文件夹中的文件
    const files = await this.getFilesByFolder(fid, folder.uid);
    for (const file of files) {
      await this.deleteFile(file.fid);
    }

    // 删除文件夹本身
    await this.delete('folders', fid);
  }

  // 文件相关方法
  async createFile(fileData) {
    const defaultFile = {
      fid: this.generateId(),
      uid: fileData.uid,
      folderId: fileData.folderId || 0,
      name: fileData.name,
      type: fileData.type || 'file',
      content: fileData.content || '',
      size: fileData.size || 0,
      path: fileData.path || '',
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString()
    };
    await this.add('files', defaultFile);
    return defaultFile;
  }

  async getFilesByFolder(folderId, uid) {
    const allFiles = await this.getAll('files');
    return allFiles.filter(file =>
      file.folderId === folderId && file.uid === uid
    );
  }

  async updateFile(fid, updateData) {
    const file = await this.get('files', fid);
    if (!file) throw new Error('File not found');

    const updatedFile = {
      ...file,
      ...updateData,
      updatedAt: new Date().toISOString()
    };
    await this.put('files', updatedFile);
    return updatedFile;
  }

  async deleteFile(fid) {
    await this.delete('files', fid);
  }

  // 图片相关方法
  async saveImage(imageData) {
    const image = {
      id: this.generateId(),
      uid: imageData.uid,
      name: imageData.name,
      data: imageData.data, // base64数据
      type: imageData.type,
      size: imageData.size,
      createdAt: new Date().toISOString()
    };
    await this.add('images', image);
    return image;
  }

  async getImagesByUser(uid) {
    const images = await this.getAll('images');
    return images.filter(img => img.uid === uid);
  }

  async deleteImage(id) {
    await this.delete('images', id);
  }

  // 博客相关方法
  async createBlog(blogData) {
    const blog = {
      bid: this.generateId(),
      uid: blogData.uid,
      title: blogData.title,
      content: blogData.content,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString()
    };
    await this.add('blogs', blog);
    return blog;
  }

  async getBlogsByUser(uid) {
    const blogs = await this.getAll('blogs');
    return blogs.filter(blog => blog.uid === uid);
  }

  async updateBlog(bid, updateData) {
    const blog = await this.get('blogs', bid);
    if (!blog) throw new Error('Blog not found');

    const updatedBlog = {
      ...blog,
      ...updateData,
      updatedAt: new Date().toISOString()
    };
    await this.put('blogs', updatedBlog);
    return updatedBlog;
  }

  async deleteBlog(bid) {
    await this.delete('blogs', bid);
  }

  // 设置相关方法
  async setSetting(key, value) {
    await this.put('settings', { key, value });
  }

  async getSetting(key) {
    const setting = await this.get('settings', key);
    return setting ? setting.value : null;
  }

  // 桌面布局相关方法
  async saveDesktopLayout(uid, layoutData) {
    await this.put('desktop', { uid, ...layoutData });
  }

  async getDesktopLayout(uid) {
    return await this.get('desktop', uid);
  }

  // 导入导出相关方法
  async exportAllData(uid) {
    const data = {
      users: await this.getAll('users'),
      folders: await this.getAll('folders'),
      files: await this.getAll('files'),
      images: await this.getAll('images'),
      blogs: await this.getAll('blogs'),
      settings: await this.getAll('settings'),
      desktop: await this.getAll('desktop'),
      exportDate: new Date().toISOString()
    };
    return JSON.stringify(data, null, 2);
  }

  async importAllData(jsonData, uid) {
    try {
      const data = JSON.parse(jsonData);

      // 清空当前用户数据
      await this.clearUserData(uid);

      // 导入数据
      if (data.folders) {
        for (const folder of data.folders.filter(f => f.uid === uid)) {
          await this.add('folders', folder);
        }
      }

      if (data.files) {
        for (const file of data.files.filter(f => f.uid === uid)) {
          await this.add('files', file);
        }
      }

      if (data.images) {
        for (const image of data.images.filter(i => i.uid === uid)) {
          await this.add('images', image);
        }
      }

      if (data.blogs) {
        for (const blog of data.blogs.filter(b => b.uid === uid)) {
          await this.add('blogs', blog);
        }
      }

      if (data.desktop) {
        const desktopData = data.desktop.find(d => d.uid === uid);
        if (desktopData) {
          await this.put('desktop', desktopData);
        }
      }

      return true;
    } catch (error) {
      console.error('Import failed:', error);
      return false;
    }
  }

  async clearUserData(uid) {
    // 删除用户的所有文件夹
    const folders = await this.getAll('folders');
    for (const folder of folders.filter(f => f.uid === uid)) {
      await this.deleteFolder(folder.fid);
    }

    // 删除用户的所有文件
    const files = await this.getAll('files');
    for (const file of files.filter(f => f.uid === uid)) {
      await this.deleteFile(file.fid);
    }

    // 删除用户的所有图片
    const images = await this.getAll('images');
    for (const image of images.filter(i => i.uid === uid)) {
      await this.deleteImage(image.id);
    }

    // 删除用户的所有博客
    const blogs = await this.getAll('blogs');
    for (const blog of blogs.filter(b => b.uid === uid)) {
      await this.deleteBlog(blog.bid);
    }

    // 删除桌面布局
    await this.delete('desktop', uid);
  }

  // 生成唯一ID
  generateId() {
    return Date.now().toString(36) + Math.random().toString(36).substr(2);
  }

  // 关闭数据库连接
  close() {
    if (this.db) {
      this.db.close();
      this.db = null;
    }
  }
}

// 创建全局实例
const indexedDBManager = new IndexedDBManager();

export default indexedDBManager;
